-
Notifications
You must be signed in to change notification settings - Fork 531
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cluster Command Parsing Refactor #373
Cluster Command Parsing Refactor #373
Conversation
29f3969
to
4c07d9b
Compare
They're the same method. There is LINQ
IMO yes. And in the cases where we want don't want to try help with a fast path (IIRC I think it was OperationDirection or something that had first fast-path check for already uppercase and then MakerUpperCase + SequenceEquals again) we could have a AsciiUtils.EqualsIgnoreCase helper which does this pattern for us. out of topic, sorta: MakeUpperCase is potentially dangerous. It has no length limit so it'll keep scanning potentially out of bounds and output the client anything that it got to. Current use of it is okay-ish, as long as nothing goes wrong (I haven't tried to craft malicious payload to it, so I think that method should have some limit..) 😅 edit: Found the place where we have "fast-path" for upper case (if we know to prioritize it for some reason) garnet/libs/server/Resp/Objects/ObjectStoreUtils.cs Lines 75 to 89 in 8856dc3
We could have something like: namespace Garnet.Common;
public static class AsciiUtils
{
public static bool EqualsIgnoreCase(byte* start, byte* end /* (or length) */, ReadOnlySpan<byte> other)
{
// get the ptrs
MakeUpperCase(start, end /* so we don't cause a heartbleed 2.0 */); // We expect "other" to be already upper case AND constant because we control it.
return span.SequenceEquals(other);
}
} but I guess in this case where all the comparisons are in the same method, it is worth it to have just one MakeUpperCase and then do comparisons against the constants. |
Thanks for the clarification. Are you saying span.SequenceEnqual is more readable? I don't have a personal preference. I pushed a new commit where I follow the pattern used in ParseCommand (i.e. MemoryMarshal.Read)
I will see if I can address this. For cluster commands, we already pay the cost of extracting a Span from the receive buffer, so it would be easy to have an uppercase bounded by the Span boundaries. I will have to benchmark the case where MakeUpperCase |
I removed MemoryExtensions and reverted back to span.SequenceEqual. Looks much better now 😄 |
MakeUpperCase does have a length limit of whatever the input buffer contains. It also stops conversion as soon as it sees a protocol character (such as \r and \n), so it should not make its way into user data even within the input buffer. |
b8a6950
to
62f8648
Compare
16d9d25
to
1187128
Compare
This PR addresses regressions due to changes in the semantics of DrainCommand and to adhere to the new parsing restrictions.
It refactors ClusterCommands.cs into multiple files similar to how other Network commands are implemented.
The PR contains the following enchantments:
Some notes: